package com.wing.member.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.common.utils.JsonResult;
import com.wing.member.model.request.RegisterForm;
import com.wing.member.dao.MemberDao;
import com.wing.member.model.entity.Member;
import com.wing.member.model.entity.MemberAuth;
import com.wing.member.model.entity.MemberRank;
import com.wing.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * 用户信息-ServiceImpl
 *
 * @author
 */
@Service
@Slf4j
public class MemberServiceImpl extends ServiceImpl<MemberDao, Member> implements MemberService {

    @Autowired
    MemberAuthService memberAuthService;
    @Autowired
    MemberRelationService memberRelationService;
    @Autowired
    MemberRankService memberRankService;

	@Override
    @Transactional(rollbackFor = Exception.class)
	public int register(RegisterForm registerForm) {

	    int flag = 0;

	    //校验邀请码
        Member parentMember = baseMapper.selectOne(new QueryWrapper<Member>().eq("invite_code", registerForm.getInviteCode()));
        if(parentMember == null){
            log.error("邀请码无效");
            throw new BusinessException(JsonResult.Code.PARAMETER_ERROR.getCode(), "member.login.inviteCode.error");
        }

        Member member;
        MemberAuth memberAuth = new MemberAuth();

	    switch (registerForm.getType()){
            case username:

                //校验用户名
                member = baseMapper.selectOne(new QueryWrapper<Member>().eq("username", registerForm.getUsername()));
                if(member != null){
                    log.error("用户名已存在");
                    throw new BusinessException(JsonResult.Code.PARAMETER_ERROR.getCode(), "member.login.username.existed");
                }

                //设置用户
                member = new Member();
                member.setType(Member.Type.app);
                member.setUsername(registerForm.getUsername());
                member.setEmail(registerForm.getIdentifier());

                //设置支付密码
                // String[] encrypt = EncryptUtil.encrypt(registerForm.getPayPassword());
                // member.setPayPassword(encrypt[0]);
                // member.setSalt(encrypt[1]);

                //设置用户授权
                memberAuth.setType(MemberAuth.Type.username);
                memberAuth.setIdentifier(member.getUsername());

                break;
            case phone:

                //校验手机号
                member = baseMapper.selectOne(new QueryWrapper<Member>().eq("phone", registerForm.getIdentifier()));
                if(member != null){
                    log.error("手机号已存在");
                    throw new BusinessException(JsonResult.Code.PARAMETER_ERROR.getCode(), "member.login.phone.existed");
                }

                //设置用户
                member = new Member();
                member.setType(Member.Type.app);
                member.setPhone(registerForm.getIdentifier());

                //设置用户授权
                memberAuth.setType(MemberAuth.Type.phone);
                memberAuth.setIdentifier(member.getPhone());

                break;
            case email:

                //校验邮箱
                member = baseMapper.selectOne(new QueryWrapper<Member>().eq("email", registerForm.getIdentifier()));
                if(member != null){
                    log.error("邮箱已存在");
                    throw new BusinessException(JsonResult.Code.PARAMETER_ERROR.getCode(), "member.login.email.existed");
                }

                //设置用户
                member = new Member();
                member.setType(Member.Type.app);
                member.setEmail(registerForm.getIdentifier());

                //设置用户授权
                memberAuth.setType(MemberAuth.Type.email);
                memberAuth.setIdentifier(member.getEmail());

                break;
            default:
                return flag;
        }

        //设置用户等级
        MemberRank memberRank = memberRankService.getOne(new QueryWrapper<MemberRank>().eq("is_default", true));
	    member.setRankId(memberRank.getId());
	    member.setRankNumber(memberRank.getSortNumber());

        //保存用户
        member.setUsername(registerForm.getUsername());
        if(parentMember != null){
            member.setParentId(parentMember.getId());
        }
        flag = this.getBaseMapper().insert(member);

        //生成用户关系
        if(flag > 0 && parentMember != null){
            flag = memberRelationService.addNode(member.getId(), parentMember.getId());
        }

        //生成用户授权登录
        // if(flag > 0){
        //     String[] encrypt = EncryptUtil.encrypt(registerForm.getPassword());
        //     memberAuth.setMemberId(member.getId());
        //     memberAuth.setCredential(encrypt[0]);
        //     memberAuth.setSalt(encrypt[1]);
        //     memberAuth.setStatus(MemberAuth.Status.Enabled);
        //     flag = memberAuthService.getBaseMapper().insert(memberAuth);
        // }

        return flag;
    }

    @Override
    public int forgotPassword(RegisterForm registerForm) {
        int flag = 0;
        Member member;
        MemberAuth memberAuth = memberAuthService.getOne(new QueryWrapper<MemberAuth>().eq("identifier", registerForm.getIdentifier()));
        switch (registerForm.getType()){
            case phone:

                //校验手机号
                member = baseMapper.selectOne(new QueryWrapper<Member>().eq("phone", registerForm.getIdentifier()));
                if(member == null || memberAuth == null){
                    log.error("手机号不存在");
                    throw new BusinessException(JsonResult.Code.PARAMETER_ERROR.getCode(), "member.login.phone.notExist");
                }

                break;
            case email:

                //校验邮箱
                member = baseMapper.selectOne(new QueryWrapper<Member>().eq("email", registerForm.getIdentifier()));
                if(member == null || memberAuth == null){
                    log.error("邮箱不存在");
                    throw new BusinessException(JsonResult.Code.PARAMETER_ERROR.getCode(), "member.login.email.notExist");
                }

                break;
            case username:

                //校验邮箱
                member = baseMapper.selectOne(new QueryWrapper<Member>().eq("username", registerForm.getIdentifier()));
                if(member == null || memberAuth == null){
                    log.error("用户名不存在");
                    throw new BusinessException(JsonResult.Code.PARAMETER_ERROR.getCode(), "member.login.email.notExist");
                }

                break;
            default:
                return flag;
        }

        // 表单密码转密文和数据库比对(与数据库密码相同时，返回成功)
        if (memberAuth != null && memberAuth.getCredential().equals(DigestUtils.sha256Hex(registerForm.getPassword() + memberAuth.getSalt()))) {
            return 1;
        }

        //修改登录密码
        // List<MemberAuth> memberAuthList = memberAuthService.list(new QueryWrapper<MemberAuth>().eq("member_id", member.getId()).in("type", new String[]{MemberAuth.Type.email.getValue().toString(), MemberAuth.Type.phone.getValue().toString(), MemberAuth.Type.username.getValue().toString()}));
        // for(MemberAuth ma : memberAuthList){
        //     String[] encrypt = EncryptUtil.encrypt(registerForm.getPassword());
        //     ma.setCredential(encrypt[0]);
        //     ma.setSalt(encrypt[1]);
        //     flag = memberAuthService.getBaseMapper().updateById(ma);
        //     if(flag <= 0){
        //         return flag;
        //     }
        // }

        return flag;
    }

    @Override
    public int forgotPayPassword(Member member, RegisterForm registerForm) {
        int flag = 0;
        switch (registerForm.getType()){
            case phone:

                //校验手机号
                member = baseMapper.selectOne(new QueryWrapper<Member>().eq("phone", member.getPhone()));
                if(member == null){
                    log.error("手机号不存在");
                    throw new BusinessException(JsonResult.Code.PARAMETER_ERROR.getCode(), "member.login.phone.notExist");
                }

                break;
            case email:

                //校验邮箱
                member = baseMapper.selectOne(new QueryWrapper<Member>().eq("email", member.getEmail()));
                if(member == null){
                    log.error("邮箱不存在");
                    throw new BusinessException(JsonResult.Code.PARAMETER_ERROR.getCode(), "member.login.email.notExist");
                }

                break;
            default:
                return flag;
        }

        //修改支付密码
        // String[] encrypt = EncryptUtil.encrypt(registerForm.getPassword());
        // member.setPayPassword(encrypt[0]);
        // member.setSalt(encrypt[1]);

        return baseMapper.updateById(member);
    }

    @Override
    public int setPayPassword(Member member, String password) {
        //设置支付密码
        // String[] encrypt = EncryptUtil.encrypt(password);
        // member.setPayPassword(encrypt[0]);
        // member.setSalt(encrypt[1]);
        return baseMapper.updateById(member);
    }

    @Override
    public int changePayPassword(Member member, String newPassword) {

        //旧支付密码校验
        /*if (!member.getPayPassword().equals(DigestUtils.sha256Hex(password + member.getSalt()))) {
            log.error("支付密码错误");
            throw new BusinessException(JsonResult.Code.PARAMETER_ERROR.getCode(), "member.login.payPassword.error");
        }*/

        // 表单密码转密文和数据库比对(与数据库密码相同时，返回成功)
        if (member.getPayPassword().equals(DigestUtils.sha256Hex(newPassword + member.getSalt()))) {
            return 1;
        }

        //修改支付密码
        // String[] encrypt = EncryptUtil.encrypt(newPassword);
        // member.setPayPassword(encrypt[0]);
        // member.setSalt(encrypt[1]);

        return baseMapper.updateById(member);
    }

    @Override
    public int binding(RegisterForm registerForm, Member member) {
        int flag = 0;
        MemberAuth memberAuth = memberAuthService.getOne(new QueryWrapper<MemberAuth>().eq("identifier", registerForm.getIdentifier()));;
        switch (registerForm.getType()){
            case phone:

                //校验手机号
                if(memberAuth != null){
                    log.error("手机号已存在");
                    throw new BusinessException(JsonResult.Code.PARAMETER_ERROR.getCode(), "member.login.phone.existed");
                }
                member.setPhone(registerForm.getIdentifier());
                break;
            case email:

                //校验邮箱
                if(memberAuth != null){
                    log.error("邮箱已存在");
                    throw new BusinessException(JsonResult.Code.PARAMETER_ERROR.getCode(), "member.login.email.existed");
                }
                member.setEmail(registerForm.getIdentifier());
                break;
            default:
                return flag;
        }

        List<MemberAuth> memberAuthList = memberAuthService.list(new QueryWrapper<MemberAuth>().eq("member_id", member.getId()).in("type", new String[]{MemberAuth.Type.email.getValue().toString(), MemberAuth.Type.phone.getValue().toString()}));
        MemberAuth addMemberAuth = new MemberAuth(registerForm.getType(), MemberAuth.Status.Enabled, member.getId(), registerForm.getIdentifier(), memberAuthList.get(0).getCredential(), memberAuthList.get(0).getSalt());
        if(memberAuthService.save(addMemberAuth)){
            flag = baseMapper.updateById(member);
        }

        return flag;
    }

    @Override
    public Page<Member> pageList4app(Page page, Map<String, Object> params) {
        List<Member> list = baseMapper.list4app(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePassword(Long id, String email, String password, String newPayPassword) {
        boolean flag = true;
        Member oldMember = this.baseMapper.selectById(id);
        //修改邮箱
        if(!oldMember.getEmail().equals(email)){
            MemberAuth memberAuth = memberAuthService.getOne(new QueryWrapper<MemberAuth>().eq("type", MemberAuth.Type.email.getValue()).eq("identifier", oldMember.getEmail()));
            memberAuth.setIdentifier(email);
            oldMember.setEmail(email);
            flag = memberAuthService.updateById(memberAuth);
        }
        //修改支付密码
        if(flag && !newPayPassword.isEmpty()){
            //修改支付密码
            // String[] encrypt = EncryptUtil.encrypt(newPayPassword);
            // oldMember.setPayPassword(encrypt[0]);
            // oldMember.setSalt(encrypt[1]);
        }
        flag = updateById(oldMember);
        //修改登录密码
        if(flag && !password.isEmpty()){
            MemberAuth memberAuth = memberAuthService.getOne(new QueryWrapper<MemberAuth>().eq("type", MemberAuth.Type.email.getValue()).eq("identifier", oldMember.getEmail()));
            // 表单密码转密文和数据库比对(与数据库密码相同时，返回成功)
            if (memberAuth.getCredential().equals(DigestUtils.sha256Hex(password + oldMember.getSalt()))) {
                flag = true;
            }else{
                //修改登录密码
                // String[] encrypt = EncryptUtil.encrypt(password);
                // memberAuth.setCredential(encrypt[0]);
                // memberAuth.setSalt(encrypt[1]);
                // flag = memberAuthService.updateById(memberAuth);
            }
        }
        return flag;
    }

    @Override
    public List<Member> list(Map<String, Object> params) {
        return baseMapper.list(params);
    }

    @Override
    public Page<Member> pageList(Page page, Map<String, Object> params) {
        List<Member> list = baseMapper.list(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    public Long getRankIdByMaxRankNumber(List<Long> memberIdList) {
        return baseMapper.getRankIdByMaxRankNumber(memberIdList);
    }

}
